#ifndef __COM_MIRROR_RTCP_H__
#define __COM_MIRROR_RTCP_H__

#include <stdlib.h>
#include <math.h>
#include <sys/param.h>
#include <net/if.h>
#include <net/if_arp.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>

#include "com_mirror_common.h"

#define RTCP_LOST_NUM_WEIGHT 0.6
#define RTCP_APP 204
#define RTCP_STATISTIC_INTERVAL 200
#define RTCP_HEAD_LENGTH    sizeof(rtcp_head)
#define ADDRESS_CHAR_LENGTH    128
#define RTCP_PACKET_LENGTH (sizeof(rtcp_head)+sizeof(HI_Mirror_RTCP_Payload))
#define FRAME_TIME_INTERVAL_IN_USECOND 1000000
#define KBYTE_IN_BYTE 1024

/*
 * RTCP common header
 */
typedef struct rtcp_common_header{
#ifdef MIRROR_BIG_ENDING
   /* protocol version */
   HI_U8 version:2;
   /* padding flag */
   HI_U8  pad_bit:1;
   /* varies by packet type */
   HI_U8  count:5;
   /* RTCP packet type */
   HI_U8  packet_type:8;
#else
   /* varies by packet type */
   HI_U8  count:5;
   /* padding flag */
   HI_U8  pad_bit:1;
   /* protocol version */
   HI_U8 version:2;

   /* RTCP packet type */
   HI_U8  packet_type:8;

#endif //endif MIRROR_BIG_ENDING

   /* pkt len in words, w/o this word */
   HI_U16 length:16;
} rtcp_head;

/*
 * RTCP msg body
 */
typedef struct rtcp_payload{
    //rtp lost number
    HI_U16 lost_rtp_num;
    //rtp packet statistical interval
    HI_U16 lost_rtp_interval;
    //draw frame rate
    HI_U16 afford_frame_rate;
    //padding for reserve
    HI_U16 padding_reserve;
} HI_Mirror_RTCP_Payload;

/*
*RTCP msg record flow control params
*/
typedef struct rtcp_packet{

    rtcp_head head;

    HI_Mirror_RTCP_Payload payload;

} HI_Mirror_RTCP_Packet;

// udp params for send rtcp packet
typedef struct RTCP_Params{
    HI_U16 portbase;
    //local port
    HI_U16 portlocal;
    //server socket
    struct sockaddr_in s_addr;
    //client address
    struct sockaddr_in c_addr;
    char clientaddress[ADDRESS_CHAR_LENGTH];
}Rtcp_Udp_Params;

//rtcp handle for flow control
typedef struct rtcp_handle
{
    //rtcp head
    rtcp_head rtcphead;
    //socket id for rtcp
    HI_S32 rtcp_sock;
    // rtcp packet
    HI_Mirror_RTCP_Packet rtcppacket;
    // udp params for send rtcp
    Rtcp_Udp_Params udpparams;

} HI_RTCP_Handler;

/**
 *@ Description:Init work for rtcp handle
 *@ param prtcp_handle - pointer to flow control handle.
 *@ param pclient_address - rtp port.
 *@ param client_port - pointer to flow control handle.
 *@ param local_port - rtp port.
 *@ return success:HI_SUCCESS,failure:HI_FAILURE.
 */
HI_S32 Init_Rtcp_Udp(HI_RTCP_Handler *prtcp_handle,const char * pclient_address,unsigned short client_port , unsigned short local_port);

/**
 *@ Description:DeInit work for rtcp handle
 *@ param prtcp_handle - pointer to rtcp handle.
 *@ return success:HI_SUCCESS,failure:HI_FAILURE
 */
HI_S32 DeInit_Rtcp_Udp(HI_RTCP_Handler *prtcphandle);

/**
 *@ Description:according to rtcp handle to send rtp lost num and afford frame rate to server
 *@ param prtcp_handle - pointer to rtcp handle.
 *@ return success:HI_SUCCESS,failure:HI_FAILURE
 */
HI_S32 Send_Rtcp_Udp(HI_RTCP_Handler *prtcphandle);

/**
 *@ Description:calculate the weighted lost num
 *@ param cur_lost_num - current packet's lost num.
 *@ param last_lost_num - last lost num.
 *@ return weighted lost packet num.
 */
HI_S32 Cal_weighted_lost_num(HI_S32 cur_lost_num,HI_S32 last_lost_num);

#endif //define  __COM_MIRROR_RTCP_H__
